#ifndef RX3DRENDERASPECT_H
#define RX3DRENDERASPECT_H

#include <RXShadowWorld/RXAspect.h>

#include "RX3DCore/RX3DCoreTypes.h"
#include "RX3D_global.h"

class RXBasicAspectService;
class RX3DCoreService;
class RX3DRenderService;
class RX3DMeshShadowNode;
class RX3DCameraShadowNode;
class RX3DTextureShadowNode;
class RX3DShaderProgramShadowNode;
class RX3DMaterialShadowNode;
class RX3DRenderActorShadowNode;
class RX3DMeshAssetShadowNode;
class RX3DOutputInterface;

class RX3DPainter;

class RX3D_EXPORT RX3DRenderAspect :public RXAspect
{
private:
	struct OutputInterfaceData
	{
		RX3DOutputInterface* out = NULL;
		RX3DPainter* painter = NULL;
		bool asset_inited = false;
	};

public:
	RX3DRenderAspect();
	~RX3DRenderAspect();


	RXECSDef::AspectJobList CreateAspectJob(std::chrono::system_clock::duration delta) override;

protected:
	void OnNodeDestoried(RXECSDef::NodeId ret) override;

private:
	enum DirtyMark
	{
		None,
		MeshAsset,
		TextureAsset,
		ShaderProgramAsset,
		MaterialAsset,
		RenderActorAsset,
		Camera,
		Render,
		MeshComp
	};
	void MarkDirty(DirtyMark mark);
	void AspectBegin() override;

	void UpdateWorldMatrix();
	void UpdateOutputPort();
	void UpdateAsset();
	void UpdateViewPort();
	void UpdateMesh();
	void UpdateCamera();
private:
	class RX3DServiceImp;
	RX3DCoreService* core_3d_service;
	RXBasicAspectService* base_Service;

	RX3DRenderService* render_service;

	ShadowNodeFactoryBase* cameraNodes;
	ShadowNodeFactoryBase* meshNodes;
	ShadowNodeFactoryBase* rendererNodes;

	ShadowNodeFactoryBase* MaterialAssetNodes;
	ShadowNodeFactoryBase* MeshAssetNodes;
	ShadowNodeFactoryBase* RenderActorAssetNodes;
	ShadowNodeFactoryBase* ShaderAssetNodes;
	ShadowNodeFactoryBase* ShaderProgramAssetNodes;
	ShadowNodeFactoryBase* TextureAssetAssetNodes;

	std::map<RX3DOutputInterface*, OutputInterfaceData> m_Output;

	DirtyMark m_eDirty;
	friend class RXSceneShadowNode;
	friend class RX3DServiceImp;
	friend class RX3DRendererShadowNode;
	friend class RX3DMeshShadowNode;
	friend class RX3DCameraShadowNode;
	friend class RX3DTextureShadowNode;
	friend class RX3DShaderProgramShadowNode;
	friend class RX3DMaterialShadowNode;
	friend class RX3DRenderActorShadowNode;
	friend class RX3DMeshAssetShadowNode;

	friend class RX3DPainter;
};


#endif // !RX3DRENDERASPECT_H
